 /**
 * DISCLIMER: 
 * this library is an opensource, feel free to edit or redistribute it
 * but use it with you own risk
 * 
 * ktutnik
 */
package org.ticlib.task
{
	import mx.core.IMXMLObject;
	import mx.rpc.AbstractOperation;
	import mx.rpc.AsyncToken;
	import mx.rpc.Responder;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	
	public class ServiceInvoker extends Task implements IMXMLObject
	{
		private var id:String;
		[Bindable] public var operation:AbstractOperation;
		[Bindable] public var arguments:Object;
		
		/**
		 * function provide conversion to result
		 * if not specified then ResultEvent.result will use as result
		 * signature:
		 * 		function(rawData:Object):Object;
		 * */
		[Bindable] public var resultConverter:Function;
		
		private var responder:Responder;
		
		public function ServiceInvoker()
		{
			super();
			responder = new Responder(onResult, onFault);
		}
		
		override public function stop():void
		{
			if(!isComplete)
			{
				operation.cancel();
				isComplete = true;
			}
			if((chain) && (!chain.isComplete))
				chain.stop();
			dispatchEvent(new Event(Event.CANCEL));
		}
		
		override public function execute():void
		{
			initialize();
			operation.arguments = this.arguments;
			var token:AsyncToken = operation.send();
			token.addResponder(responder);
		}
		
		private function onResult(e:ResultEvent):void
		{
			if(resultConverter != null)
				resultObject = resultConverter.apply(this, [e.result]);
			else
				resultObject = e.result;
			isComplete = true;
			dispatchEvent(new Event(Event.COMPLETE));
			
			//execute next task (only on conditional task)
			if((chain) &&(!parent.isComplete)) 
			{
				chain.execute();
			}
		}
		
		private function onFault(e:FaultEvent):void
		{
			faultObject = e.fault;
			dispatchEvent(FaultEvent.createEvent(e.fault));
		}
		
		public function initialized(document:Object, id:String):void
		{
			this.id = id;
		}
	}
}